1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.custom;
15 
16 
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.graphics.*;
19 import org.eclipse.swt.widgets.*;
20 
21 /**
22  * Support for showing a Busy Cursor during a long running process.
23  *
24  * @see <a href="http://www.eclipse.org/swt/snippets/#busyindicator">BusyIndicator snippets</a>
25  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
26  */
27 public class BusyIndicator {
28 
29 	static int nextBusyId = 1;
30 	static final String BUSYID_NAME = "SWT BusyIndicator"; //$NON-NLS-1$
31 	static final String BUSY_CURSOR = "SWT BusyIndicator Cursor"; //$NON-NLS-1$
32 
33 	/**
34 	 * Runs the given <code>Runnable</code> while providing
35 	 * busy feedback using this busy indicator.
36 	 *
37 	 * @param display the display on which the busy feedback should be
38 	 *        displayed.  If the display is null, the Display for the current
39 	 *        thread will be used.  If there is no Display for the current thread,
40 	 *        the runnable code will be executed and no busy feedback will be displayed.
41 	 * @param runnable the runnable for which busy feedback is to be shown.
42 	 *        Must not be null.
43 	 *
44 	 * @exception IllegalArgumentException <ul>
45 	 *    <li>ERROR_NULL_ARGUMENT - if the runnable is null</li>
46 	 * </ul>
47 	 */
48 
showWhile(Display display, Runnable runnable)49 	public static void showWhile(Display display, Runnable runnable) {
50 		if (runnable == null)
51 			SWT.error(SWT.ERROR_NULL_ARGUMENT);
52 		if (display == null) {
53 			display = Display.getCurrent();
54 			if (display == null) {
55 				runnable.run();
56 				return;
57 			}
58 		}
59 
60 		Integer busyId = Integer.valueOf(nextBusyId);
61 		nextBusyId++;
62 		Cursor cursor = display.getSystemCursor(SWT.CURSOR_WAIT);
63 		Shell[] shells = display.getShells();
64 		for (Shell shell : shells) {
65 			Integer id = (Integer)shell.getData(BUSYID_NAME);
66 			if (id == null) {
67 				setCursorAndId(shell, cursor, busyId);
68 			}
69 		}
70 
71 		try {
72 			runnable.run();
73 		} finally {
74 			shells = display.getShells();
75 			for (Shell shell : shells) {
76 				Integer id = (Integer)shell.getData(BUSYID_NAME);
77 				if (id == busyId) {
78 					setCursorAndId(shell, null, null);
79 				}
80 			}
81 		}
82 	}
83 
84 	/**
85 	 * Paranoia code to make sure we don't break UI because of one shell disposed, see bug 532632 comment 20
86 	 */
setCursorAndId(Shell shell, Cursor cursor, Integer busyId)87 	private static void setCursorAndId(Shell shell, Cursor cursor, Integer busyId) {
88 		if (!shell.isDisposed()) {
89 			shell.setCursor(cursor);
90 		}
91 		if (!shell.isDisposed()) {
92 			shell.setData(BUSYID_NAME, busyId);
93 		}
94 	}
95 }
96